﻿// --------------------------------
// <copyright file="GameStatePacket.cs" company="Faculty of Information Technology, Czech Technical University in Prague">
//     This document is shared by Microsoft Public License (MS-PL)
//     For further details please see http://msdn.microsoft.com/en-us/library/ff648068.aspx or license.txt.
// </copyright>
// <author>Lukáš Molnár</author>

// <email>molnaluk@fit.cvut.cz</email>

// <date>31. 3. 2012 17:36:23</date>

// <summary>
// 
// </summary>
// --------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FITClub.Episode1.Levels;
using LProject.Phone.Net;
using Microsoft.Xna.Framework;

namespace FITClub.Episode1.Controller.Net
{
    /// <summary>
    /// Inner type of GameState packet
    /// </summary>
    public enum GameStatePacketType : byte
    {
        NextCharacterRespawn = 1,
        //CharacterPosition
        CharacterStateL,
        CharacterStateR,
        PowerupReset,
        CharacterStatistics
    }

    /// <summary>
    /// RawPacket extension
    /// </summary>
    public class GameStatePacket
    {
        /// <summary>
        /// Length of common part in every GameState packet
        /// </summary>
        public const ushort SequenceLength = 5;
        /// <summary>
        /// Extended header length = HeaderLength + SequenceLength
        /// </summary>
        public const ushort ExtendedHeaderLength = SequenceLength + RawPacket.HeaderLength;

        /// <summary>
        /// Set this properly to get correct
        /// </summary>
        public RawPacket Packet { get; set; }

        /// <summary>
        /// Inner type of game stete packet.
        /// </summary>
        public GameStatePacketType Type
        {
            get
            {
                return (GameStatePacketType)this.Packet.Data[RawPacket.HeaderLength];
            }
            set
            {
                this.Packet.Data[RawPacket.HeaderLength] = (byte)value;
                switch (value)
                {
                    case GameStatePacketType.NextCharacterRespawn:
                        this.Packet.ContentSize = SequenceLength + 9;
                        break;
                    case GameStatePacketType.PowerupReset:
                        this.Packet.ContentSize = SequenceLength + 6;
                        break;
                    //case GameStatePacketType.CharacterStateL:
                    //case GameStatePacketType.CharacterStateR:
                    //    this.Packet.ContentSize = SequenceLength+  8;
                    //    break;
                    case GameStatePacketType.CharacterStatistics:
                        this.Packet.ContentSize = SequenceLength + 4;
                        break;
                }
            }
        }

        /// <summary>
        /// Game sequence number
        /// </summary>
        public int Sequence
        {
            get { return this.Packet.GetInt32(RawPacket.HeaderLength); }
            set { this.Packet.SetInt32(value, RawPacket.HeaderLength); }
        }

        /// <summary>
        /// Position of next character respawn point
        /// </summary>
        public Vector2 CharacterRespawn
        {
            get
            {
                return new Vector2(this.Packet.GetSingle(ExtendedHeaderLength), this.Packet.GetSingle(ExtendedHeaderLength + 4));
            }
            set
            {
                SetSingle(value.X, ExtendedHeaderLength);
                SetSingle(value.Y, ExtendedHeaderLength + 4);
            }
        }

        public byte KilledBy
        {
            get { return this.Packet.Data[ExtendedHeaderLength + 8]; }
            set { this.Packet.Data[ExtendedHeaderLength + 8] = value;}
        }

        /// <summary>
        /// Index of power up to be processed
        /// </summary>
        public byte PowerUpID
        {
            get { return this.Packet.Data[ExtendedHeaderLength]; }
            set { this.Packet.Data[ExtendedHeaderLength] = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        public PowerUpType NextPowerUpType
        {
            get { return (PowerUpType)this.Packet.Data[ExtendedHeaderLength + 1]; }
            set { this.Packet.Data[ExtendedHeaderLength + 1] = (byte)value; }
        }

        public float NextPowerUpTime
        {
            get { return this.Packet.GetSingle(ExtendedHeaderLength + 5); }
            set { SetSingle(value, ExtendedHeaderLength + 5); }
        }


        public byte Stats_Deaths
        {
            get { return this.Packet.Data[ExtendedHeaderLength]; }
            set { this.Packet.Data[ExtendedHeaderLength] = value; }
        }

        public byte Stats_Lives
        {
            get { return this.Packet.Data[ExtendedHeaderLength + 1]; }
            set { this.Packet.Data[ExtendedHeaderLength +1] = value; }
        }

        public  byte Stats_Kills
        {
            get { return this.Packet.Data[ExtendedHeaderLength + 2]; }
            set { this.Packet.Data[ExtendedHeaderLength + 2] = value; }
        }

        public byte Stats_KillStreak
        {
            get { return this.Packet.Data[ExtendedHeaderLength + 3]; }
            set { this.Packet.Data[ExtendedHeaderLength + 3] = value; }
        }


        /// <summary>
        /// Sets float value
        /// </summary>
        /// <param name="value"></param>
        /// <param name="offset">start index</param>
        public void SetSingle(float value, int offset)
        {
            byte[] us = BitConverter.GetBytes(value);
            Array.Copy(us, 0, this.Packet.Data, offset, us.Length);
        }

        /// <summary>
        /// Extracts vector from packet data.
        /// </summary>
        /// <param name="offset">start index</param>
        /// <returns></returns>
        public  Vector2 GetVector(ushort offset)
        {
           return new Vector2(this.Packet.GetSingle(offset), this.Packet.GetSingle((ushort)(offset + 4)));
        }
    }
}